//////////////////////////////////////
// Fast Container Library           //
// MIT License - Copyright (c) 2012 //
//////////////////////////////////////

#pragma once

#include <stdio.h>
#include "forward.h"
#include "basic_string_ref.h"
#include "basic_string.h"
#include "static_string.h"

//#include "fixed_string.h"

FC_NAMESPACE_BEGIN


#ifdef _MSC_VER
	#pragma warning ( push )
	#pragma warning ( disable : 4996 )
#endif


template <class T> inline
	string to_string( T value )
	{
	}

template <> inline
	string to_string( bool value )
	{
		return value ? string("true") : string("false");
	}

template <> inline
	string to_string( char value )
	{
		char buf[16];
		size_t n = to_string((int)value, buf);
		return string(buf, buf + n);
	}

template <> inline
	string to_string( short value )
	{
		char buf[16];
		size_t n = to_string((int)value, buf);
		return string(buf, buf + n);
	}

template <> inline
	string to_string( int value )
	{
		char buf[16];
		size_t n = to_string(value, buf);
		return string(buf, buf + n);
	}

template <> inline
	string to_string( size_t value )
	{
		char buf[16];
		size_t n = to_string(value, buf);
		return string(buf, buf + n);
	}

template <> inline
	string to_string( float value )
	{
		char buf[16];
		size_t n = to_string(value, buf);
		return string(buf, buf + n);
	}

template <> inline
	string to_string( double value )
	{
		char buf[16];
		size_t n = to_string(value, buf);
		return string(buf, buf + n);
	}



// string operators
/*
template <class T> inline
	fixed_string<T> operator +( const basic_string_ref<T>& a, const T* b )
	{
		fixed_string<T> s(a);
		s.append(b);
		return s;
	}

template <class T> inline
	fixed_string<T> operator +( const basic_string_ref<T>& a, T b )
	{
		fixed_string<T> s(a);
		s.push_back(b);
		return s;
	}

template <class T> inline
	fixed_string<T> operator +( const T* a, const basic_string_ref<T>& b )
	{
		fixed_string<T> s(a);
		s.append(b);
		return s;
	}

template <class T> inline
	fixed_string<T> operator +( T a, const basic_string_ref<T>& b )
	{
		fixed_string<T> s(a);
		s.append(b);
		return s;
	}

template <class T> inline
	fixed_string<T> operator +( const basic_string_ref<T>& a, const basic_string_ref<T>& b )
	{
		fixed_string<T> s;
		s.reserve(a.size() + b.size());
		s.append(a);
		s.append(b);
		return s;
	}

//string compat
template <class T, class U> inline
	fixed_string<T> operator +( const basic_string_ref<T>& a, const U& b )
	{
		fixed_string<T> s;
		s.reserve(a.size() + b.size());
		s.append(a);
		s.append(b.begin(), b.end());
		return s;
	}
*/

/*
// experimental
template <class T, class U> inline
	basic_string<T> operator +( const basic_string_ref<T>& a, const U& b )
	{
		//basic_string<T> s( uninitialized_construct() );
		basic_string<T> s( uninitialized_construct(), a.size() + b.size() );
		//s.reserve( a.size() + b.size() );
		s.append(a);
		s.append(b.begin(), b.end());
		return s;
	}
*/



template <class T> inline
	basic_string<T> operator +( const basic_string_ref<T>& a, const T* b )
	{
		const size_t n = char_traits<T>::length(b);
		basic_string<T> s( uninitialized_construct(), a.size() + n, 2 );
		//s.reserve( a.size() + char_traits<T>::length(b) );
		s.append_unchecked(a);
		s.append_unchecked(b, n);
		return s;
	}

template <class T> inline
	basic_string<T> operator +( const basic_string_ref<T>& a, T b )
	{
		basic_string<T> s( uninitialized_construct(), a.size() + 1, 2 );
		//s.reserve( a.size() + 1 );
		s.append_unchecked(a);
		s.push_back_unchecked(b);
		return s;
	}

template <class T> inline
	basic_string<T> operator +( const T* a, const basic_string_ref<T>& b )
	{
		const size_t n = char_traits<T>::length(a);
		basic_string<T> s( uninitialized_construct(), n + b.size(), 2 );
		//s.reseve( char_traits<T>::length(a) + b.size() );
		s.append_unchecked(a, n);
		s.append_unchecked(b);
		return s;
	}

template <class T> inline
	basic_string<T> operator +( T a, const basic_string_ref<T>& b )
	{
		basic_string<T> s( uninitialized_construct(), b.size() + 1, 2 );
		//s.reserve( b.size() + 1 );
		s.push_back_unchecked(a);
		s.append_unchecked(b);
		return s;
	}

template <class T> inline
	basic_string<T> operator +( const basic_string_ref<T>& a, const basic_string_ref<T>& b )
	{
		//uninitialized_construct uc;
		basic_string<T> s;//( uc, a.size() + b.size(), 2 );
		s.reserve( a.size() + b.size() );
		s.append_unchecked(a);
		s.append_unchecked(b);
		return s;
	}

#ifdef _MSC_VER
	#pragma warning ( pop )
#endif


FC_NAMESPACE_END
